<?php

/**
* @file
* Contains \Drupal\gdlisnet\Form\SettingsForm.
*/

namespace Drupal\gdlisnet\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

/**
* Configure Database Source of gdlisnet
*/
class SettingsForm extends ConfigFormBase {
	/**
	* {@inheritdoc}
	*/
	public function getFormId() {
		return 'gdlisnet_settings';
	}
	
	/**
	* {@inheritdoc}
	*/
	protected function getEditableConfigNames() {
		return ['gdlisnet.datasource', 'gdlisnet.qyweixin'];
	}
	
	/**
	* {@inheritdoc}
	*/
	public function buildForm(array $form, FormStateInterface $form_state) {
		$gdlisnet_datasource = $this->config('gdlisnet.datasource');
		$form=[];
		$form['datasource']=array(
			'#type'=>'details',
			'#title'=>$this->t('Data source settings'),
			'#open'=>TRUE,
		);
		$form['datasource']['host']=array(
			'#type' => 'textfield',
			'#title' => $this->t('Host'),
			'#default_value' => empty($gdlisnet_datasource->get('host'))?'':$gdlisnet_datasource->get('host'),
			'#required' => TRUE,
		);
		$form['datasource']['port']=array(
			'#type' => 'number',
			'#min' => 1,
			'#title' => $this->t('Port'),
			'#default_value' => empty($gdlisnet_datasource->get('port'))?'1521':$gdlisnet_datasource->get('port'),
			'#required' => TRUE,
		);
		$form['datasource']['database']=array(
			'#type' => 'textfield',
			'#title' => $this->t('Database Name'),
			'#default_value' => empty($gdlisnet_datasource->get('database'))?'':$gdlisnet_datasource->get('database'),
			'#required' => TRUE,
		);
		$form['datasource']['username']=array(
			'#type' => 'textfield',
			'#title' => $this->t('Username'),
			'#default_value' => empty($gdlisnet_datasource->get('username'))?'':$gdlisnet_datasource->get('username'),
			'#required' => TRUE,
		);
		$form['datasource']['password']=array(
			'#type' => 'textfield',
			'#title' => $this->t('Password'),
			'#description' => $this->t('Please note that, the password will be stored unencrypted as we need to run this interface unattended.'),
			'#default_value' => empty($gdlisnet_datasource->get('password'))?'':$gdlisnet_datasource->get('password'),
			'#required' => TRUE,
		);
		
		$should_show_qyweixin=\Drupal::moduleHandler()->moduleExists('qyweixin');
		$qyweixin_config=$this->config('gdlisnet.qyweixin');
		$form['qyweixin']=array(
			'#type'=>'details',
			'#title'=>$this->t('Qiye Weixin settings'),
			'#open'=>TRUE,
			'#tree'=>TRUE,
			'#access'=>$should_show_qyweixin,
		);
		$form['qyweixin']['notify_overdue']=array(
			'#type' => 'checkbox',
			'#title' => $this->t('Notify reader if the book he borrowed is overdued, once per day.'),
			'#default_value' => empty($qyweixin_config->get('notify_overdue'))?'':$qyweixin_config->get('notify_overdue'),
		);
		$form['qyweixin']['notify_upcoming']=array(
			'#type' => 'checkbox',
			'#title' => $this->t('Notify reader if the book he borrowed is expected to overduded.'),
			'#default_value' => empty($qyweixin_config->get('notify_upcoming'))?'':$qyweixin_config->get('notify_upcoming'),
		);
		$form['qyweixin']['notify_upcoming_days']=array(
			'#type' => 'textfield',
			'#title_display' => 'none',
			'#field_prefix' => $this->t('&nbsp;before:'),
			'#field_suffix'=>$this->t('days.'),
			'#size' => 10,
			'#title' => $this->t('Days before overdue'),
			'#description' => $this->t('like: 1, 3, 6'),
			'#default_value' => empty($qyweixin_config->get('notify_upcoming_days'))?'':$qyweixin_config->get('notify_upcoming_days'),
			'#states' => array(
				'visible' => array(
					':input[name="qyweixin[notify_upcoming]"]' => ['checked' => TRUE],
				),
				'required' => array(
					':input[name="qyweixin[notify_upcoming]"]' => ['checked' => TRUE],
				),
			),
		);
		$form['qyweixin']['notify_notice'] = array(
			'#type' => 'markup',
			'#markup' => $this->t('Please note that there might be huge data queued to send, which cannot fulfill in single one cron job, you\'ll need to add another queue-run command after cron in drush, if running via drush.'),
		);
		
		$form['middle_table'] = array(
			'#type' => 'details',
			'#title' => $this->t('Middle table for searching'),
			'#description' => $this->t('Please create following table and trigger in order for seaching to work.'),
			'#open' => FALSE,
		);
		
		$sqlcode = <<<EOD
CREATE TABLE 检索一对多库_日志
(主键码 NUMBER(10,0) NOT NULL ENABLE,
 时间戳 NUMBER(20,0) NOT NULL ENABLE);
CREATE OR REPLACE TRIGGER gdlisnet_collection_export
AFTER INSERT OR DELETE OR UPDATE ON 检索一对多库
FOR EACH ROW
DECLARE
v_count number;
BEGIN
if inserting OR updating then
     select count(1) into v_count from 检索一对多库_日志 where 主键码=:new.主键码;
     if v_count>0 then
         update 检索一对多库_日志 set 时间戳=((sysdate -TO_DATE('19700101','yyyymmdd'))*86400 - TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))*3600)
         where 主键码=:new.主键码;
     else
         insert into 检索一对多库_日志 VALUES(:new.主键码, ((sysdate -TO_DATE('19700101','yyyymmdd'))*86400 - TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))*3600));
     end if;
end if;
if deleting then
     select count(1) into v_count from 检索一对多库_日志 where 主键码=:old.主键码;
     if v_count>0 then
         update 检索一对多库_日志 set 时间戳=((sysdate -TO_DATE('19700101','yyyymmdd'))*86400 - TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))*3600)
         where 主键码=:old.主键码;
     else
         insert into 检索一对多库_日志 VALUES(:old.主键码, ((sysdate -TO_DATE('19700101','yyyymmdd'))*86400 - TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))*3600));
     end if;
end if;
END gdlisnet_collection_export;
EOD;
		$form['middle_table']['sqlcode']=array(
			'#type' => 'textarea',
			'#value' => $sqlcode,
			'#rows' => 30,
			'#resizable' => 'vertical',
			'#disabled' => TRUE,
		);

		return parent::buildForm($form, $form_state);
	}

	/**
	* {@inheritdoc}
	*/
	public function validateForm(array &$form, FormStateInterface $form_state) {
		if(!filter_var($form_state->getValue('host'), FILTER_VALIDATE_IP)) {
			$form_state->setErrorByName('host', $this->t('Invalid IP Address.'));
			return;
		}
		
		try {
			$conn=@oci_connect($form_state->getValue('username'),$form_state->getValue('password'),
				sprintf("%s:%s/%s", $form_state->getValue('host'), $form_state->getValue('port'), $form_state->getValue('database')), 'AL32UTF8'
			);
			if(!$conn) {
				$e=oci_error();
				throw new \Exception($e['message'], $e['code']);
			}
			
			$sql='select * from product_component_version';
			$stmt = @oci_parse($conn, $sql);
			if(!$stmt) {
				$e=oci_error($stmt);
				throw new \Exception($e['message'], $e['code']);
			}

			$r=@oci_execute($stmt, OCI_DEFAULT);
			if(!$r) {
				$e=oci_error($stmt);
				throw new \Exception($e['message'], $e['code']);
			}
		} catch (\Exception $e) {
			switch($e->getCode()) {
				case '1017':
					$form_state->setErrorByName('username', $e->getCode().': '.$e->getMessage());
					$form_state->setErrorByName('password', $e->getCode().': '.$e->getMessage());
					break;
				default:
					$form_state->setErrorByName('host', $e->getCode().': '.$e->getMessage());
			}
		} finally {
			if(!empty($stmt))
				oci_free_statement($stmt);
			if(!empty($conn))
				oci_close($conn);
		}
		
		if(!empty($form_state->getValue(['qyweixin','notify_upcoming_days']))) {
			$days=explode(',', $form_state->getValue(['qyweixin','notify_upcoming_days']));
			foreach($days as $d) {
				if(!preg_match('/^[0-9]+$/',trim($d))) {
					$form_state->setErrorByName('qyweixin][notify_upcoming_days', $this->t('The value should be in the form of "1, 3, 6"'));
				}
			}
		}
	}

	/**
	* {@inheritdoc}
	*/
	public function submitForm(array &$form, FormStateInterface $form_state) {
		$this->config('gdlisnet.datasource')
			->set('host', $form_state->getValue('host'))
			->set('port', $form_state->getValue('port'))
			->set('database', $form_state->getValue('database'))
			->set('username', $form_state->getValue('username'))
			->set('password', $form_state->getValue('password'))
			->save();
		
		if($form_state->getValue('qyweixin'))
			$this->config('gdlisnet.qyweixin')
				->set('notify_overdue', $form_state->getValue(['qyweixin', 'notify_overdue']))
				->set('notify_upcoming', $form_state->getValue(['qyweixin', 'notify_upcoming']))
				->set('notify_upcoming_days', $form_state->getValue(['qyweixin', 'notify_upcoming_days']))
				->save();

		parent::submitForm($form, $form_state);
	}
}
?>

